PVE 虚拟机相关
Table of Contents
1. Guest 系统
1.1. Windows 系
1.1.1. windows web console 鼠标不同步
显卡用默认配置的话是没有这种现象的。这个问题出现在使用 SPICE 显卡模拟功能的情况下。
虚拟机有个配置项为 tablet: <boolean> (default = 1)
,它用来启用 / 禁用被模拟出的,使用绝对坐标的 USB 指针设备。通常只有启用了该设备才能在 VNC 中使用鼠标的绝对坐标,从而使得 host 和 guest 的鼠标设备同步。
QEMU-KVM 文档 https://qemu-project.gitlab.io/qemu/system/devices/usb.html 里这么描述 usb-tablet 设备:
Pointer device that uses absolute coordinates (like a touchscreen). This means QEMU is able to report the mouse position without having to grab the mouse. Also overrides the PS/2 mouse emulation when activated.
tablet: 0
是使用 spice 终端的默认配置 (即 qm set <vmid> --vga qxl
),所以出现了 Host 的鼠标和 VNC 终端内的鼠标位置不同步的现象。
如果一台主机上运行了多台通过 VNC 终端访问的虚拟机,可以考虑在全局配置里禁用该参数,以节省不必要的上下文切换。
要在尽可能少地改动配置、尽量减少影响范围的情况下,解决鼠标同步问题,需要连接到 PVE 主机,使用 sudo vim /etc/pve/qemu-server/<vm_id>.conf
对单台虚拟机配置进行修改。加入以下语句:
... tablet: 1 # tablet: yes 也行,随后会自动地被 PVE 改写成 tablet: 1 ...
最后重启 windows 虚拟机即可解决问题。
1.1.2. Windows Server 2008 R2 设备管理器里出现 device ID 为 ACPI\QEMU\VGID 的未知设备
这是因为 Windows 7 默认没有原生的 VM Generation ID (PVE 的一个特性) 支持。只能手动安装补丁包到系统中。
下载 Hyper-V integration components update (All supported x64-based versions of Windows 7) 然后传输到虚拟机中,并安装: Dism /online /Add-Package /PackagePath:C:\<package>.cab
。
1.1.3. Windows 7 上的 virtio-win 在安装 virtio-win-gt 时报 VdService failed to start
virtio-win 官方兼容 win7 的最后一个版本是 virtio-win-0.1.173-4。但是这个版本还有一些问题。
在使用 virtio-win-gt-x64.msi 装驱动时,Spice Agent 相关的驱动有些问题,会导致 rdservice 不能启动,进而导致安装失败。
必须在 Custom Setup 阶段将 Spice Agent 组件设为 Feature will be installed when required 以跳过安装 Spice Agent 组件才能继续后面的安装过程。
但是要注意,如果 virtio-win-0.1.173-4 用在 Windows Server 2008R2 上,那么 virtio-win-gt-x64.msi 除了 Spice Agent 之外什么都装不上,而且唯一要装的 Spice Agent 还有问题,所以跑完什么都没装上。所有驱动必须自己手动装上去。
1.2. Linux 系虚拟机笔记
1.2.1. openwrt 无法关闭
可能是 openwrt 系统里缺 QEMU Guest Agent 这个包。
ssh 进 openwrt,安装 qemu-ga 即可:
opkg update opkg install qemu-ga
如果使用的固件没有 opkg 一类的包管理器,那么只能在重新编译的时候把 qemu-ga 一起编译进去。
2. 通用的性能优化方法
2.1. 磁盘映射与 VertIO SCSI 控制器
第一步,获取硬盘信息。SSH 连接到 PVE 物理机执行 ls /dev/disk/by-id/
得到硬盘 ID 的第一列大概长这样:
# 这是一块硬盘的 ID ata-HGST_HUS728T8TALE6L4_VDGW2G2D # 这是上面 ID 对应硬盘的一个分区 ata-HGST_HUS728T8TALE6L4_VDGW2G2D-part1 # 这是上面 ID 对应硬盘的另一个分区 ata-HGST_HUS728T8TALE6L4_VDGW2G2D-part2 ata-HGST_HUS728T8TALE6L4_VGGP235G ata-HGST_HUS728T8TALE6L4_VGGP235G-part1 ata-HGST_HUS728T8TALE6L4_VGGP235G-part2 ata-INTEL_SSDSC2BA400G3_BTTV501203BG400HGN ata-MK0800GCTZB_BTTV5295004K800JGN ata-MK0800GCTZB_BTTV5295004K800JGN-part1 ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2EMU56607 ata-WDC_WD5000AAKX-08U6AA0_WD-WCC2EMU56607-part1 dm-name-Intel400GS3700-vm--130--disk--0 dm-name-pve-root
第二步,映射硬盘,命令为 qm set <vm_id> -<controller_type><controller_id> /dev/disk/by-id/<disk_id>
。 <vm_id>
是虚拟机的真实 id, <controller_type>
是对应的控制器类型, <controller_id>
是该类型未被占用的通道,PVE 支持 sata[0-5]
以及 scsi[0-13]
。
比如执行这样的命令:
qm set 130 -scsi1 /dev/disk/by-id/ata-MK0800GCTZB_BTTV5295004K800JGN
得到的输出是这样的:
update VM 130: -scsi1 /dev/disk/by-id/ata-MK0800GCTZB_BTTV5295004K800JGN
在这条命令执行后,物理机上的磁盘 (不论是 SATA 还是 SAS 接口) 被默认的 VirtIO SCSI 控制器模拟成普通的 scsi 磁盘,在系统中显示为 /dev/sd[a-z]
。这个控制器在老版本的 PVE 需要特别指定,即在命令后加 -scsihw virtio-scsi-pci
(至少 PVE 6 不用手动写这个参数)。
常用的控制器类型有 SATA, VirtIO (也叫 VirtIO blk), VirtIO SCSI 和 VirtIO SCSI single 。
当 <controller_type>
填 virtio
(这种控制器通常被称为 VirtIO 或 VirtIO blk),虚拟硬盘在系统中显示为 /dev/vd[a-z]
。这是一种较老的半虚拟化控制器,就功能而言,它已被 VirtIO SCSI 控制器取代。
如果在 WebUI 里编辑 SCSI 控制器,可以在选项中看到 VirtIO SCSI 和 VirtIO SCSI single:
- VirtIO SCSI 控制器 (在 WebUI 创建的虚拟机默认用这个控制器) 管理下,所有磁盘共用一个 I/O 控制器。
- VirtIO SCSI single 控制器管理下,每个磁盘都会有独立的控制器,某些情况下会提升硬盘性能。
注: 在 PVE 7.3 之前,VirtIO SCSI 是默认的控制器;之后,VirtIO SCSI single 是默认的控制器。
不论主板上插了 SATA 接口的盘还是 SAS 接口的盘,CPU 核心多主频低的时候用 VirtIO SCSI single 控制器,CPU 核心少主频高的时候用 VirtIO SCSI 控制器。
如果 guest 太老,不支持 VirtIO SCSI 控制器,则可以把 -scsi[0-13]
换成 -sata[0-5]
来使用 SATA 控制器。
3. 虚拟机迁移
3.1. 踩坑
3.1.1. 虚拟机第二次备份时出错
PVE 虚拟机备份在默认情况下只存储一份,如果设定了定时备份任务,那么旧的备份会被删除。
修改方法: Web UI -> 数据中心 -> 存储 -> 双击备份所在位置的 ID -> Backup Retention -> 自定义备份文件存储逻辑。
这里的设置要参考 PVE 文档,或者直接去搜 Proxmox Backup Server - Prune Simulator 这是 PVE 官方做的备份模拟器。
3.1.2. 移动虚拟磁盘后旧磁盘无法删除
SSH 登录到 PVE 物理机,执行 qm rescan --vmid <vm_id>
后,未使用的磁盘会出现在 Web UI 上,此时可以删除。
如果还不能删,重启 PVE 物理机再从 Web UI 上删除。
也可以用命令 pvesm free <volume_id>
或 pvesm free <storage_id>:<disk_id>
(比如 pvesm free local-lvm:vm-105-disk-1
或 pvesm free local-lvm:vm-105-disk-1
) 删除虚拟磁盘。
3.2. 导出虚拟机
第一步,生成备份文件。选中虚拟机 -> 备份 -> 立即备份 -> 选定备份参数 -> 备份 。
第二步,找到备份文件。如果使用 PVE local 存储,那么在 /var/lib/vz/dump 内有 .vma.gz 压缩文件和 .log 日志文件。
最后下载这两个文件自行备份。
3.3. 从 img 文件导入虚拟机
第一步,正常创建一个虚拟机,过程中:
- 操作系统: 不使用任何介质;
- 硬盘: 随便选,反正要删掉的。
第二步,删除默认创建的硬盘: 选中虚拟机 -> 硬件 -> 选中硬盘 (比如 scsi0) -> 分离 -> 选中未使用的磁盘 -> 删除 。
第三步,把 img 文件传入 PVE 宿主机。
第四步,添加磁盘。用 SSH 连接到宿主机,执行命令导入硬盘,格式为:
qm importdisk <vm_id> /<img_file_path>/<img_file> <disk_id>
比如: qm importdisk 150 ./openwrt.img local-lvm
第五步,添加导入的磁盘: 选中虚拟机 -> 硬件 -> 选中未使用的磁盘 -> 编辑 -> 添加 。
第六步,调整启动顺序: 选中虚拟机 -> 选项 -> 引导顺序 -> 编辑 -> 选中硬盘,拖到第一位。
3.4. 虚拟机与模板的互转
虚拟机可以在 Web UI 里转成模板。
模板转虚拟机,删除 /etc/pve/qemu-server/<vm_id>.conf
文件里的 template: 1
行。
此时,虚拟机已可以正常启动。
虚拟机转模板后,虚拟机磁盘的名称也会由 vm-<vm_id>-disk-<disk_id>
变成 base-<vm_id>-disk-<disk_id>
,比如 vm-3000-disk-0 变成 base-3000-disk-0。
视需要更新虚拟磁盘的名称。但在更新虚拟磁盘名称后也要更新 /etc/pve/qemu-server/<vm_id>.conf
中 scsi0: <storage_id>:<vm_id>/<disk_name>.<disk_format>,size=<size>,ssd=1
的磁盘信息。
比如,scsi0: Intel400S3710:3000/base-3000-disk-0.qcow2,size=32G,ssd=1 更新为 scsi0: Intel400S3710:3000/base-3000-disk-0.qcow2,size=32G,ssd=1。
3.5. 让 qcow2 虚拟机硬盘文件大小与实际使用空间相等
3.5.1. 虚拟机内部写零操作
3.5.1.1. Linux 虚拟机
如果文件系统为 ext 系列,使用 zerofree 这个包能做到只对非 0 块写 0,减少非必要的写入,延长硬盘寿命。具体操作方法为:
- 用 Ubuntu 或者 Debian 的 live 镜像进入体验系统。
- 执行
sudo apt install -y zerofree
安装软件。 - 执行
sudo zerofree /dev/sda{2-3}
对分区写 0 后退出体验系统。
如果文件系统为 xfs 或者其他,那么只能用最基础的方法:
# 创建一个全 0 的大文件,对于所有的块写 0
dd if=/dev/zero of=/null.dat
# 删除这个文件
rm -f /null.dat
3.5.1.2. Windows 虚拟机
在 windows 虚拟机上,下载微软 SysinternalsSuite 套件,执行里面的 sdelete.exe: .\sdelete.exe -z c:
3.5.2. 导出精简后的磁盘文件
raw 格式虚拟磁盘文件导出到 qcow2:
# --sparse=always 稀疏拷贝,忽略全 0 数据 cp --sparse=always vm500G.raw vm500G-new.raw qemu-img convert -c -f raw -O qcow2 vm500G.raw vm500G.qcow2 # 删除第一条命令产生的 raw 文件 rm vm500G.raw
qcow2 格式的虚拟磁盘文件精简导出:
qemu-img convert -c -O qcow2 vm500G.qcow2 vm500G-mini.qcow2